package com.huike.clues.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.huike.clues.domain.dto.SysDictTypeCreateDTO;
import com.huike.clues.domain.dto.SysDictTypeListDTO;
import com.huike.clues.domain.dto.SysDictTypePageDTO;
import com.huike.clues.domain.entity.SysDictType;
import com.huike.clues.domain.vo.DictTypeListVO;
import com.huike.clues.domain.vo.OptionselectVO;
import com.huike.clues.domain.vo.SysDictTypePageVO;
import com.huike.clues.mapper.SysDictTypeMapper;
import com.huike.clues.service.ISysDictTypeService;
import com.huike.common.annotation.AutoFill;
import com.huike.common.constant.ErrorMessageConstants;
import com.huike.common.constant.MagicConstants;
import com.huike.common.core.page.TableDataInfo;
import com.huike.common.enums.FillType;
import com.huike.common.exception.BaseException;
import com.huike.common.utils.DictUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 数据字典类型信息实现类
 * @Author zhuzi
 * @Date 2023/10/15
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {

    private final SysDictTypeMapper mapper;

    private final HttpServletResponse httpServletResponse;

    /**
     * 新增字典类型
     */
    @AutoFill
    @Override
    public void createDictType(SysDictTypeCreateDTO dto) {
        // 查询字典类型，检验是否已存在
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dto.getDictName() != null, SysDictType::getDictName, dto.getDictName());
        SysDictType dictType = getOne(queryWrapper);
        if (dictType != null) {
            throw new BaseException(ErrorMessageConstants.DICT_ALREADY_EXISTS);
        }

        // 新增字典
        dictType = SysDictType.builder()
                .dictName(dto.getDictName())
                .dictType(dto.getDictType())
                .status(dto.getStatus())
                .remark(dto.getRemark())
                .createBy(dto.getCreateBy())
                .createTime(dto.getCreateTime())
                .updateBy(dto.getUpdateBy())
                .updateTime(dto.getUpdateTime())
                .build();
        log.info("Get dictType: {}", dictType);
        boolean ok = false;
        try {
            ok = save(dictType);
        } catch (Exception e) {
            throw new BaseException("字典名字相同，不能重复添加");
        }
        if (!ok) {
            throw new BaseException(ErrorMessageConstants.FAILED_TO_ADD_DICT_TYPE);
        }

        // 清空缓存
        clearCache();
    }

    /**
     * 更新字典类型
     */
    @AutoFill(FillType.UPDATE)
    @Override
    public void updateDictType(SysDictType dictType) {
        // 查询字典类型，检验是否已存在
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        if (dictType.getDictId() != null) {
            // 修改字典
            queryWrapper.eq(SysDictType::getDictId, dictType.getDictId());
            SysDictType sysDictType = getOne(queryWrapper);
            if (sysDictType == null) {
                throw new BaseException(ErrorMessageConstants.DICT_DOES_NOT_EXIST);
            }
            LambdaQueryWrapper<SysDictType> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(dictType.getDictName() != null, SysDictType::getDictName, dictType.getDictName());
            SysDictType one = getOne(queryWrapper1);
            if (one != null && !one.getDictName().equals(sysDictType.getDictName())) {
                throw new BaseException(ErrorMessageConstants.DICT_ALREADY_EXISTS);
            }
        } else {
            // 添加字典
            queryWrapper.eq(dictType.getDictName() != null, SysDictType::getDictName, dictType.getDictName());
            SysDictType sysDictType = getOne(queryWrapper);
            if (sysDictType != null) {
                throw new BaseException(ErrorMessageConstants.DICT_ALREADY_EXISTS);
            }
        }

        // 修改字典
        log.info("Get dictType: {}", dictType);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        try {
            mapper.updateDictTypeById(SysDictTypePageVO.builder()
                    .dictId(dictType.getDictId())
                    .dictName(dictType.getDictName())
                    .dictType(dictType.getDictType())
                    .status(dictType.getStatus())
                    .createTime(dictType.getCreateTime() == null ? null : dictType.getCreateTime().format(dtf))
                    .createBy(dictType.getCreateBy())
                    .updateTime(dictType.getUpdateTime() == null ? null : dictType.getUpdateTime().format(dtf))
                    .updateBy(dictType.getUpdateBy())
                    .remark(dictType.getRemark())
                    .build());
        } catch (Exception e) {
            throw new BaseException(ErrorMessageConstants.DICT_ALREADY_EXISTS);
        }

        // 清空缓存
        clearCache();
    }

    /**
     * 清空缓存
     */
    @Override
    public void clearCache() {
        DictUtils.clearDictCache();
    }

    /**
     * 字典类型分页查询
     */
    @Override
    public TableDataInfo<List<DictTypeListVO>> pageList(SysDictTypePageDTO dto) {
        SysDictTypeListDTO listDTO = SysDictTypeListDTO.builder().build();
        if (dto != null && dto.getPageNum() != null && dto.getPageSize() != null) {
            PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
            listDTO = SysDictTypeListDTO.builder()
                    .dictName(dto.getDictName())
                    .dictType(dto.getDictType())
                    .status(dto.getStatus())
                    .beginTime(dto.getParams() == null ? null : (String) dto.getParams().get("beginTime"))
                    .endTime(dto.getParams() == null ? null : (String) dto.getParams().get("endTime"))
                    .build();
        }
        com.github.pagehelper.Page<SysDictType> page = mapper.getList(listDTO);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<DictTypeListVO> collect = page.getResult().stream().map(i ->
                DictTypeListVO.builder()
                        .createBy(i.getCreateBy())
                        .createTime(i.getCreateTime() == null ? null : i.getCreateTime().format(dtf))
                        .updateBy(i.getUpdateBy())
                        .updateTime(i.getUpdateTime() == null ? null : i.getUpdateTime().format(dtf))
                        .dictId(i.getDictId())
                        .dictName(i.getDictName())
                        .dictType(i.getDictType())
                        .status(i.getStatus())
                        .build()
        ).collect(Collectors.toList());
        TableDataInfo<List<DictTypeListVO>> res = new TableDataInfo<>(collect, page.getTotal());
        res.setCode(200);
        res.setMsg("查询成功");
        return res;
    }

    /**
     * 根据字典类型id获取字典类型信息
     *
     * @param dictId 字典类型id
     * @return 字典类型信息
     */
    @Override
    public SysDictType getDictTypeById(Long dictId) {
        // 判断缓存中是否存在

        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictType::getDictId, dictId);
        SysDictType dictType = getOne(queryWrapper);
        if (dictType == null) {
            throw new BaseException(ErrorMessageConstants.DICT_DOES_NOT_EXIST);
        }

        // 存入缓存
        return dictType;
    }

    /**
     * 批量删除字典类型
     *
     * @param dictIds 字典类型id集合
     */
    @Override
    @Transactional
    public void delete(List<Long> dictIds) {
        if (mapper.getCountByIds(dictIds) > 0) {
            throw new BaseException("字典类型下有字典数据，不能删除");
        }
        mapper.deleteByIds(dictIds);

        // 删除缓存
        clearCache();
    }

    /**
     * 获取字典类型列表
     *
     * @param dto 条件字段
     */
    @Override
    public List<SysDictType> getDictTypeList(SysDictTypePageDTO dto) {
        Page<SysDictType> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(dto.getDictName() != null, SysDictType::getDictName, dto.getDictName());
        queryWrapper.like(dto.getDictType() != null, SysDictType::getDictType, dto.getDictType());
        queryWrapper.eq(dto.getStatus() != null, SysDictType::getStatus, dto.getStatus());
        if (dto.getParams() != null) {
            queryWrapper.between(SysDictType::getCreateTime, dto.params.get(MagicConstants.BEGIN_TIME), dto.params.get(MagicConstants.END_TIME));
        }
        page(page, queryWrapper);
        return page.getRecords();
    }

    @Override
    public List<SysDictType> getDictTypeList2(SysDictTypePageDTO dto) {
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(dto.getDictName() != null, SysDictType::getDictName, dto.getDictName());
        queryWrapper.like(dto.getDictType() != null, SysDictType::getDictType, dto.getDictType());
        queryWrapper.eq(dto.getStatus() != null, SysDictType::getStatus, dto.getStatus());
        if (dto.getParams() != null) {
            queryWrapper.between(SysDictType::getCreateTime, dto.params.get(MagicConstants.BEGIN_TIME), dto.params.get(MagicConstants.END_TIME));
        }
        return list(queryWrapper);
    }

    /**
     * 获取字典选择框列表
     */
    @Override
    public List<OptionselectVO> optionselect() {
        List<SysDictType> list = list();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return list.stream().map(i ->
                OptionselectVO.builder()
                        .createBy(i.getCreateBy())
                        .createTime(i.getCreateTime().format(dtf))
                        .dictId(i.getDictId())
                        .dictName(i.getDictName())
                        .dictType(i.getDictType())
                        .status(i.getStatus())
                        .updateBy(i.getUpdateBy())
                        .updateTime(i.getUpdateTime().format(dtf))
                        .build()
        ).collect(Collectors.toList());
    }

    /**
     * 导出字典数据
     *
     * @param dto
     */
//    @Override
//    public void export(SysDictTypePageDTO dto) {
//        try (
//                //1.读取类路径下文件：template/字典类型报表模型.xlsx
//                InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/1697374804803字典类型.xlsx");
//                //2.创建工作薄
//                XSSFWorkbook workbook = new XSSFWorkbook(in);
//                //获取浏览器输出流
//                ServletOutputStream out = httpServletResponse.getOutputStream()
//        ) {
//            //读取工作表
//            XSSFSheet sheet = workbook.getSheetAt(0);
//            //调用分页查询
//            TableDataInfo<List<SysDictTypePageVO>> list = pageList(dto);
//            //得到总条数
//            List<SysDictTypePageVO> rows = list.getRows();
//            //遍历插入
//            for (int i = 0; i < rows.size(); i++) {
//                //获取集合数据
//                SysDictTypePageVO sysDictTypePageVO = rows.get(i);
//                //获取集合总条数+1
//                XSSFRow row = sheet.getRow(i+1);
//                //获取字典主键
//                row.getCell(0).setCellValue(sysDictTypePageVO.getDictId());
//                //获取字典名称
//                row.getCell(1).setCellValue(sysDictTypePageVO.getDictName());
//                //获取字典类型
//                row.getCell(2).setCellValue(sysDictTypePageVO.getDictType());
//                //获取状态
//                row.getCell(3).setCellValue(sysDictTypePageVO.getStatus());
//            }
//            //6.将工作薄输出给浏览器输出流，关闭资源
//            workbook.write(out);
//        } catch (Exception ex) {
//            throw new RuntimeException(ex);
//        }
//    }
}
